import axios from 'axios'
import { Toast } from 'vant';
import store from '@/store'
import router from '@/router'
// 创建axios实例对象 并且配置基地址
const request = axios.create({
    baseURL: 'http://toutiao.itheima.net'
})


// 添加请求拦截器
// 语法：request.interceptors.request.use(回调函数1,回调函数2)
// 执行时机： axios调用之后，浏览器发送网络请求之前

// 发请求之前没有错误，就调回调函数1
// 发请求之前候有错误，就调回调函数2
// 一般只会用回调函数1

// 回调函数返回什么，axios就使用什么调接口

//  关键点： 第一个回调函数的config技术 request调接口时传入的配置对象
//  在config拿到这个配置对象之前 axios中间会对这个配置对象做一些处理会自动加上一些属性 其中包括Heardes
request.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    // 如果没有携带token,那么就在回调函数1中 统一携带token
    // 判断当前vuex中有没有token
    // 如果没有不做处理 
    const user = store.state.user
    // console.log(store.state.user);
    // 
    // 优化请求拦截器 refrash_token刷新token  如果在请求中，携带了请求头，就不需要再到请求拦截器里面携带了
    if (user && user.token && !config.headers.Authorization) {
        config.headers.Authorization = `Bearer ${store.state.user.token}`
    }
    // 如果有 就给config.hearders加上
    // console.log(config);
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
// 语法:request.interceptors.response.use(callback1,callback2)
// 两个回调函数的执行时机:
// 回调函数1 响应状态码为2开头时执行
// 回调函数2 响应状态码为非2开头 或 网络异常
// 两个回调函数返回的是什么？ axios的调用拿到的是什么
request.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数 响应的数据 为 2开头的状态码 才会执行到这里
    // 对响应数据做点什么
    return response.data || response;
}, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    // 错误提示优化 非2开头的状态码 会被第二个回调函数所捕获
    // 请求成功 业务失败
    if (error.response) {
        console.log(error.response);
        // 处理token过期  退出登录
        if (error.response.status === 401) {
            // refresh_token 刷新token优化
            // 1. 判断vuex中有没有refresh_token
            // 如果没有就清空token，并跳转到登录页
            const user = store.state.user
            if (user && user.refresh_token) {
                // 2. 如果有refresh_token,就使用refresh_token去调刷新token的接口获取最新得token
                request({
                    method: 'PUT',
                    url: `/v1_0/authorizations`,
                    headers: {
                        Authorization: `Bearer ${user.refresh_token}`
                    }
                }).then(res => {
                    // 2.1 如果调刷新token的接口成功，就拿最新的token替换过期的token
                    store.commit('setUser', {
                        token: res.data.token,
                        refresh_token: user.refresh_token
                    })
                    // console.log(res);
                    // error.config 就是原来的axios调用信息
                    // 把错误的token置空,在请求拦截器中处理  空字符串转换为布尔值为fasle  那么就会进入到自动携带请求头的代码中拉
                    error.config.headers.Authorization = ''
                    // 2.2 拿到原来调接口的信息，重新调接口 拿到数据返回给调用者  
                    // 把一整个配置对象传过去
                    return request(error.config)
                }).catch(err => {
                    // 如果刷新token失败，就意味着refresh_token过期了 那么清除token 跳转到登录页面
                    // console.log('token过期了');
                    // 清空token
                    store.commit('setUser', null)
                    // 跳转到登录页面
                    router.push('/login')
                })
            } else {
                // 清空token
                store.commit('setUser', null)
                // 跳转到登录页面
                router.push('/login')
            }
        }
        Toast.fail(error.response.data.message);
    } else {
        // 网络错误
        Toast.fail("网络错误");
    }
    return Promise.reject(error);
});
export default request